package cn.com.jrj.job;

import java.util.Calendar;
import java.util.List;
import java.util.Map;

import cn.com.jrj.base.exception.ApplicationException;
import cn.com.jrj.domain.Quote;
import cn.com.jrj.domain.StockInfo;
import cn.com.jrj.service.QuoteService;
import cn.com.jrj.service.SmsService;
import cn.com.jrj.service.StockService;

/**
 * 股价预警work<BR>
 * 1. 从t_mystock表中查出所有设置了短信预警的股票代码<BR>
 * 2. 从行情接口读取股票行情<BR>
 * 3. 写入行情到t_stock_quote表中<BR>
 * 4. 查询满足条件的自选股记录(带用户的ID和手机号,不含没手机号的)<BR>
 * 5. 调用短信接口下发短信,记录下发日志.<BR>
 * 6. 更新已经下了预警发短信的自选股的短信下发状态. <BR>
 * 注:<BR>
 * 1. 非交易日,此任务不执行.<BR>
 * 2. 每天开盘前,要重置所有自选股的短信下发状态<BR>
 * 3. 每天天盘前,先删除行情临时表,再创建行情临时表<BR>
 * 4. 行情信息存储在行情临时表##t_stock_quote中<BR>
 * 
 * @author xiaoyu.dou
 * 
 */
public class StockWarnWork extends VnetBaseWork {

	/***/
	private StockService stockService;

	private QuoteService quoteService;

	private SmsService smsService;

	/**
	 * 每次请求行情时，发送的股票数量
	 */
	private final static int FETCH_SIZE = 200;

	/** 任务上一次运行时的日期, 默认为 Sunday */
	private static int lastRunDay = 1;

	/** 当天是否是交易日 */
	private static boolean isTradeDay = true;
	
	/** 行情临时表是否已经创建 */
	private static boolean isHasQuoteTable = false;

	protected void executeInternal(Map<String, Object> params) throws ApplicationException, InterruptedException {
		try {
			Calendar c = Calendar.getInstance();
			int today = c.get(Calendar.DAY_OF_WEEK);
			// 判断任务上次运行日期是否是今天
			if (lastRunDay != today) {
				// 判断当天是否是交易日
				isTradeDay = this.isTradeDay();
				
				// 如果是交易日,则执行初始化工作
				if (isTradeDay) {
					// 重置自选股的短信下发状态
					int tempInt = this.stockService.doResetSmsStatus();
					log.info("ZZZ: doResetSmsStatus finished. " + tempInt + " records updated.");

					// 重新创建行情临时表
					tempInt = this.stockService.doRecreatQuoteTable();
					if (tempInt == 1) {
						isHasQuoteTable = true;
						log.info("ZZZ: recreate ##T_Stock_Quote success.");
					} else {
						isHasQuoteTable = false;
						log.error("ZZZ: recreate ##T_Stock_Quote error.");
					}
				}
				// 将上次任务运行日期设置为今天
				lastRunDay = today;
			}

			if (!isHasQuoteTable) {
				// 如果没有成功创建行情临时表,直接退出
				return;
			}

			if (!isTradeDay || !this.isTradeTime()) {
				// 如果是非交易日 或者 非交易时间,则直接退出
				return;
			}

			// 1. 从t_mystock表中查出所有设置了短信预警的股票代码
			String[] codeArray = this.stockService.getSmsWarnStockcode();
			if (codeArray.length == 0) {
				// 设置短信预警的自选股数量为0,则直接退出
				log.info("ZZZ: the SmsWarn stock count = 0, return.");
				return;
			}

			// 2. 从行情接口读取股票行情
			long begin = System.currentTimeMillis();
			List<Quote> allQuote = this.quoteService.getQuoteList(codeArray, FETCH_SIZE);
			long end = System.currentTimeMillis();
			log.info("ZZZ: query hq finished.  use time: " + (end - begin));

			// 3. 写入行情到t_stock_quote表中
			int insertCount = this.stockService.doAddQuotes(allQuote);
			log.info("ZZZ: insert quote finished. " + insertCount + " records inserted.");

			// 4. 查询满足条件的自选股记录(带用户的ID和手机号,没手机号的不算)
			List<StockInfo> stockInfoList = stockService.getMyStockInfoList();
			log.info("ZZZ: get to be sent records: " + stockInfoList.size());

			// 5. 调用短信接口下发短信,记录下发日志.
			String sentMystockIds = this.smsService.sendMessage(stockInfoList);

			// 6. 更新已经下了预警发短信的自选股的短信下发状态.
			if (sentMystockIds.length() > 0) {
				int i = this.stockService.doBatchUpdateSmsStatus(sentMystockIds);
				log.info("ZZZ: update sent mystock finished. " + i + " records updated.");
			} else {
				log.info("ZZZ: no sms sent.");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public StockService getStockService() {
		return stockService;
	}

	public void setStockService(StockService stockService) {
		this.stockService = stockService;
	}

	public QuoteService getQuoteService() {
		return quoteService;
	}

	public void setQuoteService(QuoteService quoteService) {
		this.quoteService = quoteService;
	}

	public SmsService getSmsService() {
		return smsService;
	}

	public void setSmsService(SmsService smsService) {
		this.smsService = smsService;
	}
}
